package com.lhczf.lucenedb.service;

import com.lhczf.lucenedb.util.SpringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.io.*;
import java.nio.file.Path;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@Slf4j
@Service
public class ZipServer {
    static final int BUFFER = 8192;

    public boolean initZipInfoAndZip(List<Path> paths) throws IOException {
        String backDir = SpringUtil.getProperValue("system.lucenedb.index.backup");
        LocalDateTime localDateTime = LocalDateTime.now().minusDays(1);
        String dataStr = localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        String zipName = "indexback" + dataStr + ".zip";
        File zipFile = new File(backDir + File.separator + zipName);

        return compress(zipFile, paths);
    }

    private boolean compress(File destFile, List<Path> paths) throws IOException {
        try (FileOutputStream fileOutputStream = new FileOutputStream(destFile)) {
            ZipOutputStream out = new ZipOutputStream(fileOutputStream);
            String basedir = "";
            for (Path path : paths) {
                File file = path.toFile();
                if (!file.exists()) {
                    log.warn("被压缩的目录不存在.{}", file.getAbsolutePath());
                    continue;
                }
                compress(file, out, basedir);
            }
            out.close();
        } catch (FileNotFoundException e) {
            log.error("", e);
        }
        return true;
    }

    private void compress(File file, ZipOutputStream out, String basedir) throws IOException {
        /* 判断是目录还是文件 */
        if (file.isDirectory()) {
            this.compressDirectory(file, out, basedir);
        } else {
            this.compressFile(file, out, basedir);
        }
    }

    /**
     * 压缩一个目录
     */
    private void compressDirectory(File dir, ZipOutputStream out, String basedir) throws IOException {
        if (!dir.exists()) return;
        File[] files = dir.listFiles();
        for (int i = 0; i < files.length; i++) {
            compress(files[i], out, basedir + dir.getName() + File.separator);
        }
    }

    /**
     * 压缩一个文件
     */
    private void compressFile(File file, ZipOutputStream out, String basedir) throws IOException {
        if (!file.exists()) return;
        try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file))) {
            ZipEntry entry = new ZipEntry(basedir + file.getName());
            out.putNextEntry(entry);
            int count;
            byte[] data = new byte[BUFFER];
            while ((count = bis.read(data, 0, BUFFER)) != -1) {
                out.write(data, 0, count);
            }
        } catch (FileNotFoundException e) {
            log.error("", e);
        }
    }
}
